package com.leoman.indexapi.service.Impl;

import com.leoman.adsindex.dao.AdsIndexDao;
import com.leoman.adsindex.entity.AdsIndex;
import com.leoman.adsindex.entity.vo.AdsIndexVo;
import com.leoman.barrage.dao.BarrageDao;
import com.leoman.barrage.entity.Barrage;
import com.leoman.entity.Configue;
import com.leoman.entity.Constant;
import com.leoman.exception.CommentNotFindException;
import com.leoman.exception.ParamsErrorException;
import com.leoman.exception.UserSpeakErrorException;
import com.leoman.exception.WorkNotFindException;
import com.leoman.indexapi.service.UserTaskApiService;
import com.leoman.indexapi.service.WorkApiService;
import com.leoman.message.entity.vo.MessageVo;
import com.leoman.post.dao.CommentPraiseDao;
import com.leoman.post.dao.PostBaseDao;
import com.leoman.post.dao.PostCommentDao;
import com.leoman.post.entity.PostBase;
import com.leoman.post.entity.vo.PostImageVo;
import com.leoman.reourceapi.service.impl.ResourceApiServiceImpl;
import com.leoman.systemsetting.entity.UserTask;
import com.leoman.user.dao.UserCollectDao;
import com.leoman.user.dao.UserInfoDao;
import com.leoman.user.entity.UserCollect;
import com.leoman.user.entity.UserInfo;
import com.leoman.userapi.service.UserIntegralService;
import com.leoman.utils.DateUtils;
import com.leoman.utils.ImageUtil;
import com.leoman.utils.XmlUtil;
import com.leoman.work.dao.*;
import com.leoman.work.entity.*;
import com.leoman.work.entity.vo.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 作品实现ServiceImpl
 * Created by Administrator on 2016/6/12.
 */
@Service
public class WorkApiServiceImplApi implements WorkApiService {

    @Autowired
    private WorkDao workDao;

    @Autowired
    private WorkVideoDao workVideoDao;

    @Autowired
    private WorkNovelDao workNovelDao;

    @Autowired
    private WorkComicDao workComicDao;

    @Autowired
    private WorkComicImageDao workComicImageDao;

    @Autowired
    private WorkCommentDao workCommentDao;

    @Autowired
    private WorkRecommendDao workRecommendDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private BarrageDao barrageDao;

    @Autowired
    private UserCollectDao userCollectDao;

    @Autowired
    private WorkCreatorDao workCreatorDao;

    @Autowired
    private AdsIndexDao adsIndexDao;

    @Autowired
    private PostCommentDao postCommentDao;

    @Autowired
    private WorkSurroundDao workSurroundDao;

    @Autowired
    private CommentPraiseDao commentPraiseDao;

    @Autowired
    private PostBaseDao postbasedao;

    @Autowired
    private UserTaskApiService userTaskApiService;

    @Autowired
    private UserIntegralService userIntegralService;

    @Override
    public List<Work> iFindList(String time) throws ParamsErrorException {
        List<Work> list = new ArrayList<>();
        List<WorkRecommend> recommendList;

        try {
            if (StringUtils.isNotEmpty(time)) {
                time = DateUtils.longToString(System.currentTimeMillis(), "yyyy-MM-dd");
            }
            String startTime = time + " 00:00:00";
            String endTime = time + " 23:59:59";
            Long startDate = DateUtils.stringToLong(startTime, "yyyy-MM-dd hh:mm:ss");
            Long endDate = DateUtils.stringToLong(endTime, "yyyy-MM-dd hh:mm:ss");
            list = workDao.iFindList(startDate, endDate);
            for (Work work : list) {
                recommendList = workRecommendDao.findListByParams(work.getId(), work.getCategory().getType());
                work.setPosition(work.getCategory().getType());
                work.setCover(ImageUtil.clearUploadUrl(work.getCover()));
                if (null != recommendList && recommendList.size() > 0) {
                    work.setWorkId(recommendList.get(0).getSourceId());
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return list;
    }

    @Override
    public List<AdsIndexVo> iFindList() {
        List<AdsIndex> adsIndexList = adsIndexDao.findAll();
        List<AdsIndexVo> list = new ArrayList<>();
        AdsIndexVo adsIndexVo;
        UserInfo userInfo;
        PostBase postBase;
        String[] params;

        for (AdsIndex adsIndex : adsIndexList) {
            adsIndexVo = new AdsIndexVo();
            adsIndexVo.setId(adsIndex.getId());
            adsIndexVo.setTitle(adsIndex.getTitle());
            adsIndexVo.setSubTitle(adsIndex.getSubTitle());
            adsIndexVo.setCover(ImageUtil.clearUploadUrl(adsIndex.getSuolue()));
            adsIndexVo.setPosition(adsIndex.getPosition());
            if (adsIndex.getPosition() == 0) {
                adsIndexVo.setWorkId(Long.parseLong(postbasedao.findOne(adsIndex.getWorkId()).getType().toString()));
            } else {
                adsIndexVo.setWorkId(adsIndex.getCategoryId());
            }
            adsIndexVo.setDetailId(adsIndex.getWorkId());

            switch (adsIndex.getPosition()) {
                case 0:
                    // 0:帖子
                    // 查询主创回复数和粉丝回复数
                    adsIndexVo.setCreatorBarrageNum(postCommentDao.findListByParams(adsIndex.getWorkId(), Constant.COMMENT_TYPE_DEFAULT, Constant.IF_CREATOR_YES).size());
                    adsIndexVo.setBarrageNum(postCommentDao.findListByParams(adsIndex.getWorkId(), Constant.COMMENT_TYPE_DEFAULT, Constant.IF_CREATOR_NO).size());
                    break;
                case 1:
                    // 1:视频
                case 3:
                    // 3:漫画
                    // 查询主创弹幕数和粉丝弹幕数
                    adsIndexVo.setCreatorBarrageNum(barrageDao.iFindList3(adsIndex.getWorkId(), Constant.IF_CREATOR_YES).size());
                    adsIndexVo.setBarrageNum(barrageDao.iFindList3(adsIndex.getWorkId(), Constant.IF_CREATOR_NO).size());
                    break;
            }

            switch (adsIndex.getPosition()) {
                case 0:
                    postBase = postbasedao.findOne(adsIndex.getWorkId());
                    adsIndexVo.setAuthorHead(ImageUtil.clearUploadUrl(postBase.getUserInfo().getAvater()));
                    adsIndexVo.setAuthorName(postBase.getUserInfo().getNickname());
                    break;
                case 1:
                case 2:
                case 3:
                    params = getNameAndHead(adsIndex.getCategoryId());
                    adsIndexVo.setAuthorName(params[0]);
                    adsIndexVo.setAuthorHead(params[1]);
                    break;
                case 4:
                case 5:
                    userInfo = userInfoDao.findOneByNickname(Constant.YULEJUN);
                    adsIndexVo.setAuthorName(userInfo.getNickname());
                    adsIndexVo.setAuthorHead(ImageUtil.clearUploadUrl(userInfo.getAvater()));
                    break;
            }

            list.add(adsIndexVo);
        }

        return list;
    }

    private String[] getNameAndHead(Long workId) {
        String[] params = new String[2];

        List<WorkCreator> workCreatorList = workCreatorDao.findWorkId(workId);
        if (null == workCreatorList || workCreatorList.size() == 0) {
            params[0] = "";
            params[1] = "";
        } else {
            UserInfo userInfo = workCreatorList.get(0).getUserInfo();
            params[0] = userInfo.getNickname();
            params[1] = StringUtils.isNotEmpty(userInfo.getAvater()) ? ImageUtil.clearUploadUrl(userInfo.getAvater()) : "";
        }

        return params;
    }

    @Override
    public Page<WorkVideoVo> videoPage(Long userId, Integer pageNum, Integer pageSize) {
        // 视频
        final Page<Work> workPage = workDao.findCollectListByUserIdAndType(userId, Constant.CATEGORY_TYPE_004, Constant.COLLECT_TYPE_001, new PageRequest(pageNum - 1, pageSize));
        return getVideoPage(workPage);
    }

    @Override
    public Page<WorkVideoVo> videoPage(Integer pageNum, Integer pageSize) {
        // 视频
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        final Page<Work> workPage = workDao.findCollectListByType(Constant.CATEGORY_TYPE_004, new PageRequest(info[0] - 1, info[1]));
        return getVideoPage(workPage);
    }

    private Page<WorkVideoVo> getVideoPage(final Page<Work> workPage) {
        return new Page<WorkVideoVo>() {
            @Override
            public int getNumber() {
                return workPage.getNumber();
            }

            @Override
            public int getSize() {
                return workPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return workPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return workPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return workPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return workPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return workPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return workPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return workPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return workPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return workPage.previousPageable();
            }

            @Override
            public Iterator<WorkVideoVo> iterator() {
                return new Iterator<WorkVideoVo>() {
                    @Override
                    public boolean hasNext() {
                        return workPage.iterator().hasNext();
                    }

                    @Override
                    public WorkVideoVo next() {
                        try {
                            return getWorkVideoVo(workPage.iterator().next());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                };
            }

            @Override
            public List<WorkVideoVo> getContent() {
                List<WorkVideoVo> list = new ArrayList<>();

                try {
                    for (Work work : workPage.getContent()) {
                        list.add(getWorkVideoVo(work));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return workPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return workPage.getSort();
            }
        };
    }

    @Override
    public Page<WorkComicVo> comicPage(Long userId, Integer pageNum, Integer pageSize) {
        // 漫画
        final Page<Work> workPage = workDao.findCollectListByUserIdAndType(userId, Constant.CATEGORY_TYPE_006, Constant.COLLECT_TYPE_003, new PageRequest(pageNum - 1, pageSize));
        return getComicPage(workPage);
    }

    @Override
    public Page<WorkComicVo> comicPage(Integer pageNum, Integer pageSize) {
        // 漫画
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        final Page<Work> workPage = workDao.findCollectListByType(Constant.CATEGORY_TYPE_006, new PageRequest(info[0] - 1, info[1]));
        return getComicPage(workPage);
    }

    private Page<WorkComicVo> getComicPage(final Page<Work> workPage) {
        return new Page<WorkComicVo>() {
            @Override
            public int getNumber() {
                return workPage.getNumber();
            }

            @Override
            public int getSize() {
                return workPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return workPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return workPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return workPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return workPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return workPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return workPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return workPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return workPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return workPage.previousPageable();
            }

            @Override
            public Iterator<WorkComicVo> iterator() {
                return new Iterator<WorkComicVo>() {
                    @Override
                    public boolean hasNext() {
                        return workPage.iterator().hasNext();
                    }

                    @Override
                    public WorkComicVo next() {
                        try {
                            return getWorkComicVo(workPage.iterator().next());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                };
            }

            @Override
            public List<WorkComicVo> getContent() {
                List<WorkComicVo> list = new ArrayList<>();

                try {
                    for (Work work : workPage.getContent()) {
                        list.add(getWorkComicVo(work));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return workPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return workPage.getSort();
            }
        };
    }

    @Override
    public Page<WorkNovelVo> novelPage(Long userId, Integer pageNum, Integer pageSize) {
        // 小说
        final Page<Work> workPage = workDao.findCollectListByUserIdAndType(userId, Constant.CATEGORY_TYPE_005, Constant.COLLECT_TYPE_002, new PageRequest(pageNum - 1, pageSize));
        return getNovelPage(workPage);
    }

    @Override
    public Page<WorkNovelVo> novelPage2(Integer pageNum, Integer pageSize) {
        // 小说
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        final Page<Work> workPage = workDao.findCollectListByType(Constant.CATEGORY_TYPE_005, new PageRequest(info[0] - 1, info[1]));
        return getNovelPage(workPage);
    }

    private Page<WorkNovelVo> getNovelPage(final Page<Work> workPage) {
        return new Page<WorkNovelVo>() {
            @Override
            public int getNumber() {
                return workPage.getNumber();
            }

            @Override
            public int getSize() {
                return workPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return workPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return workPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return workPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return workPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return workPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return workPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return workPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return workPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return workPage.previousPageable();
            }

            @Override
            public Iterator<WorkNovelVo> iterator() {
                return new Iterator<WorkNovelVo>() {
                    @Override
                    public boolean hasNext() {
                        return workPage.iterator().hasNext();
                    }

                    @Override
                    public WorkNovelVo next() {
                        try {
                            return getWorkNovelVo(workPage.iterator().next());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                };
            }

            @Override
            public List<WorkNovelVo> getContent() {
                List<WorkNovelVo> list = new ArrayList<>();

                try {
                    for (Work work : workPage.getContent()) {
                        list.add(getWorkNovelVo(work));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return workPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return workPage.getSort();
            }
        };
    }

    private List<WorkVideoDetailVo> getWorkVideoDetailList(Long workId) {
        List<WorkVideoDetailVo> list = new ArrayList<>();
        List<WorkVideo> workVideoList = workVideoDao.findByWorkIdNoOrder(workId);
        WorkVideoDetailVo workVideoDetailVo;

        for (WorkVideo workVideo : workVideoList) {
            workVideoDetailVo = new WorkVideoDetailVo();
            workVideoDetailVo.setId(workVideo.getId());
            workVideoDetailVo.setName(workVideo.getName());
            workVideoDetailVo.setSeries(workVideo.getSeries());
            workVideoDetailVo.setSite(workVideo.getSite());
            workVideoDetailVo.setLinkUrl(workVideo.getLinkUrl());
            workVideoDetailVo.setPlayNum(workVideo.getPlayNum());
            workVideoDetailVo.setBarrageNum(workVideo.getBarrageNum());
            workVideoDetailVo.setVid(workVideo.getVid());

            list.add(workVideoDetailVo);
        }

        return list;
    }

    @Override
    public WorkVideoVo findVideo(Long workId, Long userId) throws ParamsErrorException, WorkNotFindException {
        try {
            if (null == workId) {
                throw new ParamsErrorException();
            }

            Work work = getWork(workId);
            WorkVideoVo workVideoVo = getWorkVideoVo(work);

            if (null == workVideoVo) {
                throw new WorkNotFindException();
            }

            if (null != userId) {
                List<UserCollect> userCollectList = userCollectDao.findListByParams(userId, workId, Constant.COLLECT_TYPE_001);
                workVideoVo.setIsCollect(null == userCollectList || userCollectList.size() == 0 ? 0 : 1);
            } else {
                workVideoVo.setIsCollect(0);
            }

            // 查询视频详情列表
            workVideoVo.setWorkVideoDetailList(getWorkVideoDetailList(workVideoVo.getId()));

            // 查询主创列表
            workVideoVo.setCreatorList(getWorkCreatorList(workId));

            // 查询周边推荐列表
            workVideoVo.setSurroundList(getWorkSurroundList(workId));

            // 修改视频播放量
            work.setPlayNum(work.getPlayNum() + 1);
            workDao.save(work);

            return workVideoVo;
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (WorkNotFindException e) {
            throw new WorkNotFindException();
        }
        return null;
    }

    @Override
    public WorkComicVo findComic(Long workId, Long userId) throws ParamsErrorException, WorkNotFindException {
        try {
            if (null == workId) {
                throw new ParamsErrorException();
            }

            Work work = getWork(workId);
            WorkComicVo workComicVo = getWorkComicVo(work);

            if (null == workComicVo) {
                throw new WorkNotFindException();
            }

            // 获取漫画章节详情
            workComicVo.setDetailList(getComicDetail(workId));

            if (null != userId) {
                List<UserCollect> userCollectList = userCollectDao.findListByParams(userId, workId, Constant.COLLECT_TYPE_003);
                workComicVo.setIsCollect(null == userCollectList || userCollectList.size() == 0 ? 0 : 1);
            } else {
                workComicVo.setIsCollect(0);
            }

            // 查询主创列表
            workComicVo.setCreatorList(getWorkCreatorList(workId));

            // 查询周边推荐列表
            workComicVo.setSurroundList(getWorkSurroundList(workId));

            // 修改播放量
            work.setPlayNum(work.getPlayNum() + 1);
            workDao.save(work);

            return workComicVo;
        } catch (WorkNotFindException e) {
            throw new WorkNotFindException();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据漫画id获取对应的章节列表
     */
    private List<WorkComicDetailVo> getComicDetail(Long workId) {
        List<WorkComicDetailVo> list = new ArrayList<>();
        WorkComicDetailVo workComicDetailVo;

        List<WorkComic> workComicList = workComicDao.findByWorkId(workId);

        for (WorkComic workComic : workComicList) {
            workComicDetailVo = new WorkComicDetailVo();
            workComicDetailVo.setId(workComic.getId());
            workComicDetailVo.setName(workComic.getName());
            workComicDetailVo.setSeries(workComic.getSeries());
            workComicDetailVo.setPlayNum(workComic.getPlayNum());
            workComicDetailVo.setBarrageNum(workComic.getBarrageNum());

            list.add(workComicDetailVo);
        }

        return list;
    }

    @Override
    public WorkNovelVo findNovel(Long workId, Long userId) throws ParamsErrorException, WorkNotFindException {
        try {
            if (null == workId) {
                throw new ParamsErrorException();
            }

            Work work = getWork(workId);
            WorkNovelVo workNovelVo = getWorkNovelVo(work);

            if (null == workNovelVo) {
                throw new WorkNotFindException();
            }

            // 获取小说内容
            List<WorkNovel> list = workNovelDao.findByWorkId(workId);
            WorkNovelDetailVo workNovelDetailVo;
            List<WorkNovelDetailVo> workNovelDetailVoList = new ArrayList<>();
            for (WorkNovel workNovel : list) {
                workNovelDetailVo = new WorkNovelDetailVo();
                workNovelDetailVo.setId(workNovel.getId());
                workNovelDetailVo.setName(workNovel.getName());
                workNovelDetailVo.setSeries(workNovel.getSeries());
                workNovelDetailVo.setUpdateTime(workNovel.getUpdateDate());

                workNovelDetailVoList.add(workNovelDetailVo);
            }

            workNovelVo.setDetailList(workNovelDetailVoList);

            if (null != userId) {
                List<UserCollect> userCollectList = userCollectDao.findListByParams(userId, workId, Constant.COLLECT_TYPE_002);
                workNovelVo.setIsCollect(null == userCollectList || userCollectList.size() == 0 ? 0 : 1);
            } else {
                workNovelVo.setIsCollect(0);
            }

            // 查询主创列表
            workNovelVo.setCreatorList(getWorkCreatorList(workId));

            // 查询周边推荐列表
            workNovelVo.setSurroundList(getWorkSurroundList(workId));

            // 修改播放量
            work.setPlayNum(work.getPlayNum() + 1);
            workDao.save(work);

            return workNovelVo;
        } catch (WorkNotFindException e) {
            throw new WorkNotFindException();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String findNovelContent(Long workNovelId) throws ParamsErrorException, WorkNotFindException {
        if (null == workNovelId) {
            throw new ParamsErrorException();
        }

        WorkNovel workNovel = workNovelDao.findOne(workNovelId);

        if (null == workNovel) {
            throw new WorkNotFindException();
        }

        return workNovel.getDetail().replaceAll("&lt", "<").replaceAll("&gt", ">");
    }

    @Override
    public List<PostImageVo> findComicContent(Long workComicId) throws ParamsErrorException, WorkNotFindException {
        if (null == workComicId) {
            throw new ParamsErrorException();
        }

        WorkComic workComic = workComicDao.findOne(workComicId);

        if (null == workComic) {
            throw new WorkNotFindException();
        }

        List<WorkComicImage> comicImageList = workComicImageDao.findByComicId(workComicId);
        List<PostImageVo> list = new ArrayList<>();
        PostImageVo postImageVo;

        for (WorkComicImage workComicImage : comicImageList) {
            postImageVo = new PostImageVo();
            postImageVo.setUrl(ImageUtil.clearUploadUrl(workComicImage.getUrl()));
            postImageVo.setSuolue(ImageUtil.clearUploadUrl(workComicImage.getSuolue()));

            list.add(postImageVo);
        }

        return list;
    }

    private List<WorkSurroundVo> getWorkSurroundList(Long workId) {
        List<WorkSurround> workSurrounds = workSurroundDao.findByWorkId(workId);
        List<WorkSurroundVo> list = new ArrayList<>();
        WorkSurroundVo workSurroundVo;

        for (WorkSurround workSurround : workSurrounds) {
            workSurroundVo = new WorkSurroundVo();
            workSurroundVo.setId(workSurround.getId());
            workSurroundVo.setTitle(workSurround.getWelfare().getTitle());
            workSurroundVo.setSubTitle(workSurround.getWelfare().getSubTitle());
            workSurroundVo.setType(workSurround.getType());
            workSurroundVo.setDescription(workSurround.getWelfare().getDescription());
            if (!workSurround.getWelfare().getType().equals(Constant.WELFARE_TYPE_004)) {
                if (StringUtils.isNotEmpty(workSurround.getWelfare().getUrl())) {
                    workSurroundVo.setLinkUrl(ImageUtil.clearUploadUrl(workSurround.getWelfare().getUrl()));
                }
            } else {
                workSurroundVo.setLinkUrl(workSurround.getWelfare().getUrl());
            }
            workSurroundVo.setCover(ImageUtil.clearUploadUrl(workSurround.getWelfare().getCover()));

            list.add(workSurroundVo);
        }

        return list;
    }

    @Override
    public Page<WorkCommentVo> iPageByParams(Long workId, Integer type, Integer status, final Long userId, Integer pageNum, Integer pageSize) {
        int[] info = ResourceApiServiceImpl.changePageParams(pageNum, pageSize);
        final Page<WorkComment> workCommentPage = workCommentDao.iPage(workId, type, status, new PageRequest(info[0] - 1, info[1]));
        return new Page<WorkCommentVo>() {
            @Override
            public int getNumber() {
                return workCommentPage.getNumber();
            }

            @Override
            public int getSize() {
                return workCommentPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return workCommentPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return workCommentPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return workCommentPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return workCommentPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return workCommentPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return workCommentPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return workCommentPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return workCommentPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return workCommentPage.previousPageable();
            }

            @Override
            public Iterator<WorkCommentVo> iterator() {
                final Iterator<WorkComment> workCommentIterator = workCommentPage.iterator();
                return new Iterator<WorkCommentVo>() {
                    @Override
                    public boolean hasNext() {
                        return workCommentIterator.hasNext();
                    }

                    @Override
                    public WorkCommentVo next() {
                        return getWorkCommentVo(workCommentIterator.next(), userId);
                    }
                };
            }

            @Override
            public List<WorkCommentVo> getContent() {
                List<WorkComment> workCommentList = workCommentPage.getContent();
                List<WorkCommentVo> list = new ArrayList<>();

                for (WorkComment workComment : workCommentList) {
                    list.add(getWorkCommentVo(workComment, userId));
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return workCommentPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return workCommentPage.getSort();
            }
        };
    }

    @Override
    public void saveWorkComment(Integer status, Long workId, Integer type, Long userId, String content) throws ParamsErrorException, UserSpeakErrorException, WorkNotFindException {
        if (null == status || null == workId || null == type || null == userId || !StringUtils.isNotEmpty(content)) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (userInfo.getStatus().equals(Constant.USER_STATUS_GAG)) {
            throw new UserSpeakErrorException();
        }

        Work work = null;
        WorkVideo workVideo = null;
        WorkNovel workNovel = null;
        WorkComic workComic = null;

        if (status == 0) {
            work = workDao.findOne(workId);

            if (null == work) {
                throw new WorkNotFindException();
            }
        } else {
            switch (type) {
                case 4:
                    workVideo = workVideoDao.findOne(workId);
                    break;
                case 5:
                    workNovel = workNovelDao.findOne(workId);
                    break;
                case 6:
                    workComic = workComicDao.findOne(workId);
                    break;
            }

            if (null == workVideo && null == workNovel && null == workComic) {
                throw new WorkNotFindException();
            }
        }

        try {
            WorkComment workComment = new WorkComment();
            workComment.setUserInfo(userInfo);
            workComment.setWorkId(workId);
            workComment.setType(type);
            workComment.setPraise(0);
            if (status == 0) {
                workComment.setName(work.getName());
            } else {
                switch (type) {
                    case 4:
                        workComment.setName(workVideo.getName());
                        workComment.setToUserInfo(workCreatorDao.findByWorkIds(workVideo.getWork().getId()).get(0).getUserInfo());
                        break;
                    case 5:
                        workComment.setName(workNovel.getName());
                        workComment.setToUserInfo(workCreatorDao.findByWorkIds(workNovel.getWork().getId()).get(0).getUserInfo());
                        break;
                    case 6:
                        workComment.setName(workComic.getName());
                        workComment.setToUserInfo(workCreatorDao.findByWorkIds(workComic.getWork().getId()).get(0).getUserInfo());
                        break;
                }
            }
            workComment.setIsDetail(status);
            workComment.setContent(content);
            workComment.setTypePlus(Constant.COMMENT_TYPE_DEFAULT);

            workCommentDao.save(workComment);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void saveWorkReply(Integer status, Long workCommentId, Long userId, String content) throws ParamsErrorException, UserSpeakErrorException, CommentNotFindException {
        if (null == status || null == workCommentId || null == userId || !StringUtils.isNotEmpty(content)) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (userInfo.getStatus().equals(Constant.USER_STATUS_GAG)) {
            throw new UserSpeakErrorException();
        }

        WorkComment workComment = workCommentDao.findOne(workCommentId);
        if (null == workComment) {
            throw new CommentNotFindException();
        }

        try {
            WorkComment tempWorkComment = new WorkComment();
            tempWorkComment.setUserInfo(userInfo);
            tempWorkComment.setToUserInfo(workComment.getUserInfo());
            tempWorkComment.setWorkCommentId(workCommentId);
            tempWorkComment.setWorkId(workComment.getWorkId());
            tempWorkComment.setType(workComment.getType());
            tempWorkComment.setPraise(0);
            tempWorkComment.setContent(content);
            tempWorkComment.setIsDetail(status);
            tempWorkComment.setTypePlus(Constant.COMMENT_TYPE_REPLY);

            workCommentDao.save(tempWorkComment);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<Barrage> iFindBarrageList(Long workId, Integer type, Integer timePlus) throws ParamsErrorException, WorkNotFindException {
        if (null == workId || null == type) {
            throw new ParamsErrorException();
        }

        List<Barrage> list;

        if (null == timePlus) {
            list = barrageDao.iFindList(workId, type);
        } else {
            list = barrageDao.iFindList2(workId, type, timePlus);
        }

        for (Barrage barrage : list) {
            // 如果是主创，返回主创头像
            if (barrage.getUserInfo().getIsCreator() == 1) {
                barrage.setCreatorAvater(ImageUtil.clearUploadUrl(barrage.getUserInfo().getSuolue()));
                barrage.setCreatorName(barrage.getUserInfo().getNickname());
            }
        }

        return list;
    }

    @Override
    @Transactional
    public void insertBarrage(Integer type, Long workId, Long userId, Integer time, Integer timePlus, String content) throws ParamsErrorException, UserSpeakErrorException {
        if (null == type || null == workId || null == userId || null == time || StringUtils.isEmpty(content)) {
            throw new ParamsErrorException();
        }

        UserInfo userInfo = userInfoDao.findOne(userId);
        if (userInfo.getStatus().equals(Constant.USER_STATUS_GAG)) {
            throw new UserSpeakErrorException();
        }

        try {
            Work work;
            String name;

            // 0：视频  1：漫画
            if (type == 0) {
                WorkVideo workVideo = workVideoDao.findOne(workId);
                work = workVideo.getWork();

                name = workVideo.getWork().getName();

                workVideo.setBarrageNum(workVideo.getBarrageNum() + 1);
                workVideoDao.save(workVideo);
            } else {
                WorkComic workComic = workComicDao.findOne(workId);
                work = workComic.getWork();

                name = workComic.getWork().getName();

                workComic.setBarrageNum(workComic.getBarrageNum() + 1);
                workComicDao.save(workComic);
            }

            Barrage barrage = new Barrage();
            barrage.setType(type);
            barrage.setWorkId(workId);
            barrage.setName(name);
            barrage.setUserInfo(userInfo);
            barrage.setPraise(0L);
            barrage.setContent(content);
            barrage.setTime(time);
            barrage.setTimePlus(timePlus);

            barrageDao.save(barrage);

            // 修改弹幕数
            work.setBarrageNum(work.getBarrageNum() + 1);
            workDao.save(work);

            // 统计作品弹幕量
            userTaskApiService.addWorkData(work, workId, 0, 1);

            // 进行发弹幕任务
            userTaskApiService.finishTask(userId, Constant.USER_TASK_TYPE_006, false);

            // 发弹幕可获得5经验值，每日最多获得20经验值
            UserTask userTask = userTaskApiService.findInfoByUserIdAndType(userId, Constant.USER_TASK_TYPE_006);
            if (userTask.getCount() <= 5) {
                userIntegralService.changeIntegral(userInfo, "发弹幕可获得20经验值", 20);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Page<MessageVo> pageMessage(Long userId, Integer type, Integer pageNum, Integer pageSize) {
        List<WorkComment> workCommentList = workCommentDao.iFindListByUserIds(userId);

        for (WorkComment workComment : workCommentList) {
            if (workComment.getIsRead().equals(Constant.MESSAGE_READ_STATUS_YES)) {
                continue;
            }
            workComment.setIsRead(Constant.MESSAGE_READ_STATUS_YES);
            workCommentDao.save(workComment);
        }

        final Page<WorkComment> workCommentPage = workCommentDao.iPageByUserId(userId, type, Constant.COMMENT_PRAISE_ISDETAIL_NO, new PageRequest(pageNum - 1, pageSize));
        return new Page<MessageVo>() {
            @Override
            public int getNumber() {
                return workCommentPage.getNumber();
            }

            @Override
            public int getSize() {
                return workCommentPage.getSize();
            }

            @Override
            public int getTotalPages() {
                return workCommentPage.getTotalPages();
            }

            @Override
            public int getNumberOfElements() {
                return workCommentPage.getNumberOfElements();
            }

            @Override
            public long getTotalElements() {
                return workCommentPage.getTotalElements();
            }

            @Override
            public boolean hasPreviousPage() {
                return workCommentPage.hasPreviousPage();
            }

            @Override
            public boolean isFirstPage() {
                return workCommentPage.isFirstPage();
            }

            @Override
            public boolean hasNextPage() {
                return workCommentPage.hasNextPage();
            }

            @Override
            public boolean isLastPage() {
                return workCommentPage.isLastPage();
            }

            @Override
            public Pageable nextPageable() {
                return workCommentPage.nextPageable();
            }

            @Override
            public Pageable previousPageable() {
                return workCommentPage.previousPageable();
            }

            @Override
            public Iterator<MessageVo> iterator() {
                final Iterator<WorkComment> workCommentIterator = workCommentPage.iterator();
                return new Iterator<MessageVo>() {
                    @Override
                    public boolean hasNext() {
                        return workCommentIterator.hasNext();
                    }

                    @Override
                    public MessageVo next() {
                        return getMessageVo(workCommentIterator.next());
                    }
                };
            }

            @Override
            public List<MessageVo> getContent() {
                List<WorkComment> workCommentList = workCommentPage.getContent();
                List<MessageVo> list = new ArrayList<>();

                for (WorkComment workComment : workCommentList) {
                    list.add(getMessageVo(workComment));
                }

                return list;
            }

            @Override
            public boolean hasContent() {
                return workCommentPage.hasContent();
            }

            @Override
            public Sort getSort() {
                return workCommentPage.getSort();
            }
        };
    }

    @Override
    public String iFindBarrageListXml(Long workId, Integer type, Integer timePlus) throws ParamsErrorException, WorkNotFindException {
        if (null == workId || null == type) {
            throw new ParamsErrorException();
        }

        List<Barrage> list;

        if (null == timePlus) {
            list = barrageDao.iFindList(workId, type);
        } else {
            list = barrageDao.iFindList2(workId, type, timePlus);
        }

        for (Barrage barrage : list) {
            // 如果是主创，返回主创头像
            if (barrage.getUserInfo().getIsCreator() == 1) {
                barrage.setCreatorAvater(ImageUtil.clearUploadUrl(barrage.getUserInfo().getSuolue()));
                barrage.setCreatorName(barrage.getUserInfo().getNickname());
            }
        }

        // 生成xml文件
        return Configue.getUploadUrls() + XmlUtil.productXml("xml/barrageXml" + System.currentTimeMillis() + ".xml", list);
    }

    @Override
    public void saveDetailData(Integer type, Long detailId) throws ParamsErrorException {
        if (null == type || null == detailId) {
            throw new ParamsErrorException();
        }

        try {
            Work work = null;
            WorkVideo workVideo;
            WorkNovel workNovel;
            WorkComic workComic;

            switch (type) {
                case 0:
                    // 视频
                    workVideo = workVideoDao.findOne(detailId);
                    if (null != workVideo) {
                        work = workVideo.getWork();
                    }
                    break;
                case 1:
                    // 漫画
                    workComic = workComicDao.findOne(detailId);
                    if (null != workComic) {
                        work = workComic.getWork();
                    }
                    break;
                case 2:
                    // 小说
                    workNovel = workNovelDao.findOne(detailId);
                    if (null != workNovel) {
                        work = workNovel.getWork();
                    }
                    break;
            }

            if (null != work) {
                userTaskApiService.addWorkData(work, detailId, 1, 0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private MessageVo getMessageVo(WorkComment workComment) {
        MessageVo messageVo = new MessageVo();
        WorkComment replyComment;

        Work work = workDao.findOne(workComment.getWorkId());
        messageVo.setId(workComment.getId());
        messageVo.setUserId(workComment.getUserInfo().getId());
        messageVo.setName(workComment.getUserInfo().getNickname());
        messageVo.setAvater(ImageUtil.clearUploadUrl(workComment.getUserInfo().getAvater()));
        messageVo.setContent(workComment.getContent());
        messageVo.setSourceId(workComment.getWorkId());
        messageVo.setSourceType(workComment.getType());
        messageVo.setSourceName(work.getName());
        if (work.getCategory().getType().equals(Constant.CATEGORY_TYPE_004)) {
            messageVo.setSourceAvater(work.getCover());
        } else {
            messageVo.setSourceAvater(ImageUtil.clearUploadUrl(work.getCover()));
        }
        if (null != workComment.getWorkCommentId()) {
            replyComment = workCommentDao.findOne(workComment.getWorkCommentId());
            messageVo.setReplyContent(replyComment.getContent());
            messageVo.setSourceContent(workDao.findOne(replyComment.getWorkId()).getName());
        }
        if (null == workComment.getToUserInfo()) {
            switch (workComment.getType()) {
                case 4:
                    messageVo.setSourceAuthor("");
                    break;
                case 5:
                    messageVo.setSourceAuthor(workComicDao.findOne(work.getId()).getAuthor());
                    break;
                case 6:
                    messageVo.setSourceAuthor(workNovelDao.findOne(work.getId()).getAuthor());
                    break;
            }
        } else {
            messageVo.setSourceAuthor("");
        }
        messageVo.setCreateDate(workComment.getCreateDate());

        // 将消息读取状态修改为已读状态
        // workComment.setIsRead(Constant.MESSAGE_READ_STATUS_YES);
        // workCommentDao.save(workComment);

        return messageVo;
    }

    private Work getWork(Long workId) throws WorkNotFindException {
        if (null == workId) {
            throw new WorkNotFindException();
        }

        Work work = workDao.findOne(workId);
        if (null == work) {
            throw new WorkNotFindException();
        }

        return work;
    }

    private WorkVideoVo getWorkVideoVo(Work work) throws ParseException, WorkNotFindException {
        if (null == work || !work.getCategory().getType().equals(Constant.CATEGORY_TYPE_004)) {
            throw new WorkNotFindException();
        }

        WorkVideoVo workVideoVo = new WorkVideoVo();
        workVideoVo.setId(work.getId());
        workVideoVo.setName(work.getName());
        workVideoVo.setSeries(workVideoDao.findByWorkId(work.getId()).size());
        workVideoVo.setAllSeries(work.getSeriesCount());
        workVideoVo.setCover(work.getCover());
        workVideoVo.setAid(work.getAlbumId());
        workVideoVo.setDescription(work.getDescription());
        workVideoVo.setPlayNum(work.getPlayNum());
        workVideoVo.setBarrageNum(work.getBarrageNum());
        workVideoVo.setIsEnd(work.getIsEnd());

        return workVideoVo;
    }

    private WorkComicVo getWorkComicVo(Work work) throws ParseException, WorkNotFindException {
        if (null == work || !work.getCategory().getType().equals(Constant.CATEGORY_TYPE_006)) {
            throw new WorkNotFindException();
        }

        List<WorkComic> tempList = workComicDao.findByWorkId(work.getId());

        WorkComic workComic = null;

        if (null != tempList && tempList.size() > 0) {
            workComic = tempList.get(0);
        }

        WorkComicVo workComicVo = new WorkComicVo();
        workComicVo.setId(work.getId());
        workComicVo.setDescription(work.getDescription());
        if (null == workComic) {
            workComicVo.setName("");
            workComicVo.setAuthor("");
            workComicVo.setSeries(0);
            workComicVo.setAllSeries(0);
            workComicVo.setUpdateTime(null);
        } else {
            workComicVo.setName(workComic.getWork().getName());
            List<WorkCreator> list = workCreatorDao.findByWorkIds(work.getId());
            workComicVo.setAuthor(null == list || list.size() == 0 ? "" : list.get(0).getUserInfo().getNickname());
            workComicVo.setSeries(tempList.size());
            workComicVo.setAllSeries(workComic.getSeries());
            workComicVo.setUpdateTime(workComic.getUpdateDate());
            workComicVo.setPlayNum(work.getPlayNum());
            workComicVo.setBarrageNum(work.getBarrageNum());
        }

        workComicVo.setCover(ImageUtil.clearUploadUrl(work.getSuolue()));
        workComicVo.setIsEnd(work.getIsEnd());

        return workComicVo;
    }

    private WorkNovelVo getWorkNovelVo(Work work) throws ParseException, WorkNotFindException {
        if (null == work || !work.getCategory().getType().equals(Constant.CATEGORY_TYPE_005)) {
            throw new WorkNotFindException();
        }

        WorkNovelVo workNovelVo = new WorkNovelVo();
        workNovelVo.setId(work.getId());
        workNovelVo.setName(work.getName());
        workNovelVo.setCover(ImageUtil.clearUploadUrl(work.getSuolue()));
        List<WorkCreator> list = workCreatorDao.findByWorkIds(work.getId());
        workNovelVo.setAuthor(null == list || list.size() == 0 ? "" : list.get(0).getUserInfo().getNickname());
        workNovelVo.setSeries(workNovelDao.findByWorkId(work.getId()).size());
        workNovelVo.setAllSeries(work.getSeriesCount());
        workNovelVo.setPlayNum(work.getPlayNum());
        workNovelVo.setDescription(work.getDescription());
        workNovelVo.setUpdateTime(work.getUpdateDate());
        workNovelVo.setIsEnd(work.getIsEnd());

        return workNovelVo;
    }

    /**
     * 拼接作品评论VO类
     */
    private WorkCommentVo getWorkCommentVo(WorkComment workComment, Long userId) {
        WorkComment baseWorkComment;
        UserInfo userInfo = workComment.getUserInfo();
        WorkCommentVo workCommentVo = new WorkCommentVo();
        workCommentVo.setId(workComment.getId());
        workCommentVo.setUserId(userInfo.getId());
        workCommentVo.setNickname(userInfo.getNickname());
        workCommentVo.setLevel(userInfo.getLevel());
        workCommentVo.setAvater(ImageUtil.clearUploadUrl(userInfo.getAvater()));
        workCommentVo.setContent(workComment.getContent());
        workCommentVo.setIsCreator(null == userInfo.getIsCreator() ? 0 : userInfo.getIsCreator());
        workCommentVo.setPraise(commentPraiseDao.findListByParams(workComment.getId(), Constant.COMMENT_PRAISE_TYPE_002, workComment.getIsDetail()).size());
        workCommentVo.setIsPraise(null != commentPraiseDao.findOneByParams(workComment.getId(), userId, Constant.COMMENT_PRAISE_TYPE_002, workComment.getIsDetail()) ? 0 : 1);
        workCommentVo.setCreateDate(workComment.getCreateDate());
        if (null != workComment.getToUserInfo() && null != workComment.getWorkCommentId()) {
            baseWorkComment = workCommentDao.findOne(workComment.getWorkCommentId());
            if (null != baseWorkComment) {
                workCommentVo.setReplyName(baseWorkComment.getUserInfo().getNickname());
                workCommentVo.setReplyContent(baseWorkComment.getContent());
            }
        }

        return workCommentVo;
    }

    /**
     * 获取主创列表
     */
    private List<WorkCreatorVo> getWorkCreatorList(Long workId) {
        List<WorkCreatorVo> list = new ArrayList<>();
        List<WorkCreator> creatorList = workCreatorDao.findWorkIdDesc(workId);
        WorkCreatorVo workCreatorVo;
        UserInfo userInfo;

        for (WorkCreator workCreator : creatorList) {
            userInfo = workCreator.getUserInfo();
            workCreatorVo = new WorkCreatorVo();
            workCreatorVo.setId(userInfo.getCreator().getId());
            workCreatorVo.setCreatorUserId(userInfo.getId());
            workCreatorVo.setName(userInfo.getNickname());
            workCreatorVo.setAvater(StringUtils.isNotEmpty(userInfo.getAvater()) ? ImageUtil.clearUploadUrl(userInfo.getAvater()) : "");
            workCreatorVo.setPraise(workCreator.getPraise());
            workCreatorVo.setCoin(workCreator.getUserInfo().getCoin());

            list.add(workCreatorVo);
        }

        return list;
    }
}
